﻿/************************************************************************************
 * xujiajun@yoozoo.com 御剑
 * 实现传递LOD百分比接口的地块层级，可以设置根据LOD百分比来计算LOD缩放的策略并返回给监听者
 ***********************************************************************************/

using System;
using WorldMapBase.Layer;
using Unity.Mathematics;
using WorldMapBase.LOD;

namespace WorldMapBase
{
    /// <summary>
    /// 实现传递LOD百分比接口的地块层级，可以设置根据LOD百分比来计算LOD缩放的策略并返回给监听者
    /// </summary>
    public class LODTileLayer : TileLayer, LODLayerContainer.ILODPercentListener
    {
        /// <summary>
        /// LOD缩放监听器
        /// </summary>
        public interface ILODScaleListener
        {
            /// <summary>
            /// LOD缩放更新时响应
            /// </summary>
            /// <param name="lodLevel">LOD等级</param>
            /// <param name="scale">缩放系数 x 100</param>
            void OnLODScaleUpdate(int lodLevel, float scale);
        }

        /// <summary>
        /// LOD缩放监听器
        /// </summary>
        private ILODScaleListener m_Listener;

        /// <summary>
        /// LOD缩放策略
        /// </summary>
        private ILODScaleStrategy m_Strategy;

        /// <summary>
        /// 上一帧的缩放值
        /// </summary>
        private float m_LastScale = -1;

        /// <summary>
        /// 构造LOD地块层级
        /// </summary>
        /// <param name="tileSize">格子尺寸</param>
        /// <param name="layerRect">层级范围（xy：左下世界坐标，zw：长宽）</param>
        public LODTileLayer(int tileSize, int4 layerRect) : base(tileSize, layerRect)
        {
            m_Strategy = DefaultLODScaleStrategy.Default;
        }

        /// <summary>
        /// 构造LOD地块层级
        /// </summary>
        /// <param name="tileSize">格子尺寸</param>
        /// <param name="layerRect">层级范围（xy：左下世界坐标，zw：长宽）</param>
        /// <param name="tileLayerListener">地块层级监听器</param>
        /// <param name="lodScaleListener">LOD缩放监听器</param>
        public LODTileLayer(int tileSize, int4 layerRect, ITileLayerListener tileLayerListener, ILODScaleListener lodScaleListener) : base (tileSize, layerRect, tileLayerListener)
        {
            m_Strategy = DefaultLODScaleStrategy.Default;
            SetLODScaleListener(lodScaleListener);
        }

        /// <summary>
        /// 设置LOD缩放的监听器
        /// </summary>
        /// <param name="listener">LOD缩放监听器</param>
        public void SetLODScaleListener(ILODScaleListener listener)
        {
            m_Listener = listener;
        }

        /// <summary>
        /// 设置LOD缩放策略
        /// </summary>
        /// <param name="strategy">LOD缩放策略</param>
        public void SetScaleStrategy(ILODScaleStrategy strategy)
        {
            m_Strategy = strategy == null ? DefaultLODScaleStrategy.Default : strategy;
        }

        public void OnUpdateLODPercent(int lodLevel, float percent)
        {
            var scale = m_Strategy.GetLODScale(percent);
            if (Math.Abs(scale - m_LastScale) > LODStrategy.LOD_PERCENT_TOLERANCE)
            {
                m_Listener?.OnLODScaleUpdate(lodLevel, scale);
                m_LastScale = scale;
            }
        }
    }

}
